import axios, { type Method } from 'axios'
import { useUserStore } from '@/stores'
import { showToast } from 'vant'
import router from '@/router'

const baseURL = 'https://consult-api.itheima.net/'
const instance = axios.create({
  baseURL,
  timeout: 5000
})

// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // !统一携带 token
    const store = useUserStore()
    if (store.user?.token) {
      config.headers['Authorization'] = `Bearer ${store.user.token}`
    }
    return config
  },
  (err) => {
    return Promise.reject(err)
  }
)

instance.interceptors.response.use(
  (res) => {
    if (res.data.code !== 10000) {
      // 业务失败了
      showToast(res.data.message)
      return Promise.reject(res.data)
    }
    // res.data 表示后端返回的数据，类似 { success, code, message, data }
    return res.data
  },
  (err) => {
    if (err.response.status === 401) {
      // 删除 token（Pinia 和本地的）
      const store = useUserStore()
      store.delUser()
      // 拦截到登录页
      // 写 returnUrl 的目的是为了下一次登录，能够回到原页面
      router.push(`/login?returnUrl=${router.currentRoute.value.fullPath}`)
    }
    return Promise.reject(err)
  }
)

// 一般用法，其实还可以再进一步封装，根据 method 来自动判断用 params 传参还是 data 传参
/* instance({
  method,
  url,
  data,
  params
}) */
/* instance({
  method,
  url,
  data,
  params
}) */

// function aaa<T>(){}

type TData<T> = {
  code: number
  message: string
  data: T
}

/* interface IData<T> {
  code: number
  message: string
  data: T
} */

const request = <T>(
  url: string,
  method: Method = 'get',
  submitData?: object
) => {
  // instance 和 instance.request 其实用法是一样的，但是 instance.request 能更好的支持泛型参数，规定返回数据的类型
  // 默认情况下，第一个泛型参数，规定的是 r.data 的类型
  // !第二个泛型参数，可以规定返回值 r 的类型
  return instance.request<T, TData<T>>({
    url,
    method,
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}

export { instance, request }
// import { instance, request } from '@/utils/request'

// export default { instance, request }
// import utilsReq from '@/utils/request'
// const { instance, request } = utilsReq

/* request<User>('/user').then((r) => {
  // !出问题了：现在 r 下面的提示不正确，应该出现的直接是后端返回的数据的提示，因为我们在封装 instance 的时候已经“解套”了
  r.data.avatar
})

request<{ username: string; age: number }>('/news').then((r) => {
  r.data.username
}) */
